home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / libraries / dylan / vec.dylan < prev   
Encoding:
Text File  |  1995-03-15  |  12.8 KB  |  447 lines  |  [TEXT/ttxt]

  1. module: dylan
  2. rcs-header: $Header: vec.dylan,v 1.15 94/11/03 23:51:13 wlott Exp $
  3.  
  4. //======================================================================
  5. //
  6. // Copyright (c) 1994  Carnegie Mellon University
  7. // All rights reserved.
  8. // 
  9. // Use and copying of this software and preparation of derivative
  10. // works based on this software are permitted, including commercial
  11. // use, provided that the following conditions are observed:
  12. // 
  13. // 1. This copyright notice must be retained in full on any copies
  14. //    and on appropriate parts of any derivative works.
  15. // 2. Documentation (paper or online) accompanying any system that
  16. //    incorporates this software, or any part of it, must acknowledge
  17. //    the contribution of the Gwydion Project at Carnegie Mellon
  18. //    University.
  19. // 
  20. // This software is made available "as is".  Neither the authors nor
  21. // Carnegie Mellon University make any warranty about the software,
  22. // its performance, or its conformity to any specification.
  23. // 
  24. // Bug reports, questions, comments, and suggestions should be sent by
  25. // E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  26. //
  27. //======================================================================
  28. //
  29. //  This file contains the support for vectors that isn't builtin.
  30. //
  31.  
  32.  
  33. //// Iteration protocol.
  34.  
  35. define constant vector-prev-state =
  36.   begin
  37.     local
  38.       method vector-prev-state (vec :: <vector>, state :: <fixed-integer>)
  39.       => <fixed-integer>;
  40.     state - 1;
  41.       end;
  42.     vector-prev-state;
  43.   end;
  44.  
  45. define constant vector-next-state =
  46.   begin
  47.     local
  48.       method vector-next-state (vec :: <vector>, state :: <fixed-integer>)
  49.       => <fixed-integer>;
  50.     state + 1;
  51.       end;
  52.     vector-next-state;
  53.   end;
  54.  
  55. define constant vector-finished? =
  56.   begin
  57.     local
  58.       method vector-finished? (vec :: <vector>, state :: <fixed-integer>,
  59.                    limit :: <fixed-integer>)
  60.     state == limit;
  61.       end;
  62.     vector-finished?;
  63.   end;
  64.  
  65. define constant vector-current-key =
  66.   begin
  67.     local
  68.       method vector-current-key (vec :: <vector>, state :: <fixed-integer>)
  69.       => <object>;
  70.     state;
  71.       end;
  72.     vector-current-key;
  73.   end;
  74.  
  75. define constant vector-current-element =
  76.   begin
  77.     local
  78.       method vector-current-element (vec :: <vector>, state :: <fixed-integer>)
  79.       => <object>;
  80.     element(vec, state);
  81.       end;
  82.     vector-current-element;
  83.   end;
  84.  
  85. define constant vector-current-element-setter =
  86.   begin
  87.     local
  88.       method vector-current-element-setter (value :: <object>, vec :: <vector>,
  89.                         state :: <fixed-integer>)
  90.       => <object>;
  91.     element(vec, state) := value;
  92.       end;
  93.     vector-current-element-setter;
  94.   end;
  95.  
  96. define constant vector-copy-state =
  97.   begin
  98.     local
  99.       method vector-copy-state (vec :: <vector>, state :: <fixed-integer>)
  100.       => <fixed-integer>;
  101.     state;
  102.       end;
  103.     vector-copy-state;
  104.   end;
  105.  
  106. define method forward-iteration-protocol (vec :: <vector>)
  107.   values(0, size(vec), vector-next-state, vector-finished?,
  108.      vector-current-key, vector-current-element,
  109.      vector-current-element-setter, vector-copy-state);
  110. end;
  111.  
  112. define method backward-iteration-protocol (vec :: <vector>)
  113.   values(size(vec) - 1, -1, vector-prev-state, vector-finished?,
  114.      vector-current-key, vector-current-element,
  115.      vector-current-element-setter, vector-copy-state);
  116. end;
  117.  
  118.  
  119. //// Collection routines.
  120.  
  121. define method \=(vec1 :: <vector>, vec2 :: <vector>)
  122.   let (size1, size2) = values(size(vec1), size(vec2));
  123.   (size1 == size2) & for (index from 0 below size1,
  124.              while vec1[index] = vec2[index])
  125.             finally
  126.               // #t iff we fell off the end
  127.               index == size1;
  128.             end for;
  129. end method \=;
  130.  
  131. // No collection alignment done here because it only handles the
  132. // all-vector case.
  133. define method map-as(cls :: <class>, function :: <function>,
  134.              vector :: <vector>,
  135.              #next next-method,
  136.              #rest more_vectors)
  137.   if (~subtype?(cls, <vector>))
  138.     next-method();
  139.   elseif (empty?(more_vectors))
  140.     let size = size(vector);
  141.     let result = make(cls, size: size);
  142.     for (key from 0 below size)
  143.       result[key] := function(vector[key]);
  144.     end for;
  145.     result;
  146.   elseif (~every?(rcurry(instance?, <vector>), more_vectors))
  147.     next-method();
  148.   else
  149.     let size = reduce(method (a, b) min(a, size(b)) end method, size(vector),
  150.               more_vectors);
  151.     let result = make(cls, size: size);
  152.     for (key from 0 below size)
  153.       result[key] := apply(function, vector[key],
  154.                map(rcurry(element, key), more_vectors));
  155.     end for;
  156.     result;
  157.   end if;
  158. end method map-as;
  159.  
  160. define method concatenate-as(cls :: <class>, vector :: <vector>,
  161.                  #next next-method,
  162.                  #rest more_vectors)
  163.   if (~subtype?(cls, <vector>) |
  164.     ~every?(rcurry(instance?, <vector>), more_vectors))
  165.     next-method();
  166.   else 
  167.     let length = reduce(method (int, seq) int + size(seq) end method,
  168.             size(vector), more_vectors);
  169.     let result = make(cls, size: length);
  170.     local method do_copy(state, vector :: <vector>) // :: state
  171.         for (state from state,
  172.          key from 0 below size(vector))
  173.           result[state] := vector[key];
  174.         finally state;
  175.         end for;
  176.       end method do_copy;
  177.     reduce(do_copy, do_copy(0, vector), more_vectors);
  178.     result;
  179.   end if;
  180. end method concatenate-as;
  181.  
  182. define method member?(value :: <object>, vector :: <vector>,
  183.               #key test = \==)
  184.   block (return)
  185.     for (key from 0 below size(vector))
  186.       if (test(value, vector[key])) return(#t) end if;
  187.     end for;
  188.   end block;
  189. end method member?;
  190.  
  191. define method empty?(vector :: <vector>)
  192.   size(vector) = 0;
  193. end method empty?;
  194.  
  195. // No collection alignment done here because it only handles the
  196. // all-vector case.
  197. define method every?(proc :: <function>, vector :: <vector>,
  198.              #next next_method,
  199.              #rest more_vectors) => <object>;
  200.   if (empty?(more_vectors))
  201.     block (return)
  202.       for (key from 0 below size(vector))
  203.     unless (proc(vector[key])) return(#f) end unless;
  204.       end for;
  205.       #t;
  206.     end block;
  207.   elseif (every?(rcurry(instance?, <vector>), more_vectors))
  208.     // since we only specify one sequence, this will not produce an infinite
  209.     // recursion.
  210.     block (return)
  211.       let sz = reduce(method(a,b) min(a, size(b)) end method,
  212.               size(vector), more_vectors);
  213.       for (key from 0 below size)
  214.     let result = apply(proc, vector[key],
  215.                map(rcurry(element, key), more_vectors));
  216.     unless (result) return(#f) end unless;
  217.       end for;
  218.       #t;
  219.     end block;
  220.   else
  221.     next_method();
  222.   end if;
  223. end method every?;
  224.  
  225. define method subsequence-position(big :: <vector>, pattern :: <vector>,
  226.                    #key test = \==, count = 1)
  227.   let sz = size(big);
  228.   let pat-sz = size(pattern);
  229.  
  230.   select (pat-sz)
  231.     0 =>
  232.       0;
  233.     1 =>
  234.       let ch = pattern[0];
  235.       for (key from 0 below sz,
  236.        until test(big[key], ch) & (count := count - 1) <= 0)
  237.       finally
  238.     if (key < sz) key end if;
  239.       end for;
  240.     2 =>
  241.       let ch1 = pattern[0];
  242.       let ch2 = pattern[1];
  243.       for (key from 0 below sz - 1,
  244.        until test(big[key], ch1) & test(big[key + 1], ch2)
  245.          & (count := count - 1) <= 0)
  246.       finally
  247.     if (key < (sz - 1)) key end if;
  248.       end for;
  249.     otherwise =>
  250.       local method search(index, big-key, pat-key, count)
  251.           case
  252.         pat-key >= pat-sz =>  // End of pattern -- We found one.
  253.           if (count = 1) index
  254.           else search(index + 1, index + 1, 0, count - 1);
  255.           end if;
  256.         big-key = sz =>          // End of big vector -- it's not here.
  257.           #f;
  258.         test(big[big-key], pattern[pat-key]) =>
  259.           // They match -- try one more.
  260.           search(index, big-key + 1, pat-key + 1, count);
  261.         otherwise =>          // Don't match -- try one further along.
  262.           search(index + 1, index + 1, 0, count);
  263.           end case;
  264.         end method search;
  265.       search(0, 0, 0, count);
  266.   end select;
  267. end method subsequence-position;
  268.  
  269. define method subsequence-position(big :: <byte-string>,
  270.                    pattern :: <byte-string>,
  271.                    #key test = \==, count = 1)
  272.   let sz = size(big);
  273.   let pat-sz = size(pattern);
  274.  
  275.   select (pat-sz)
  276.     0 =>
  277.       0;
  278.     1 =>
  279.       let ch = pattern[0];
  280.       for (key from 0 below sz,
  281.        until test(big[key], ch) & (count := count - 1) <= 0)
  282.       finally
  283.     if (key < sz) key end if;
  284.       end for;
  285.     2 =>
  286.       let ch1 = pattern[0];
  287.       let ch2 = pattern[1];
  288.       for (key from 0 below sz - 1,
  289.        until test(big[key], ch1) & test(big[key + 1], ch2)
  290.          & (count := count - 1) <= 0)
  291.       finally
  292.     if (key < (sz - 1)) key end if;
  293.       end for;
  294.     otherwise =>
  295.       if (test ~= \==)
  296.     local method search(index, big-key, pat-key, count)
  297.         case
  298.           pat-key >= pat-sz =>  // End of pattern -- We found one.
  299.             if (count = 1) index
  300.             else search(index + 1, index + 1, 0, count - 1);
  301.             end if;
  302.           big-key = sz =>      // End of big vector -- it's not here.
  303.             #f;
  304.           test(big[big-key], pattern[pat-key]) =>
  305.             // They match -- try one more.
  306.             search(index, big-key + 1, pat-key + 1, count);
  307.           otherwise =>         // Don't match -- try one further along.
  308.             search(index + 1, index + 1, 0, count);
  309.         end case;
  310.           end method search;
  311.     search(0, 0, 0, count);
  312.       else
  313.     // It's worth doing something Boyer-Moore-ish....
  314.     let pat-last = pat-sz - 1;
  315.     let last-char = pattern[pat-last];
  316.     let skip = make(<vector>, size: 256, fill: pat-sz);
  317.     for (i from 0 below pat-last)
  318.       skip[as(<fixed-integer>, pattern[i])] := pat-last - i;
  319.     end for;
  320.     local method do-skip(index, count)
  321.         if (index >= sz)
  322.           #f;
  323.         else 
  324.           let char = big[index];
  325.           if (char == last-char)
  326.             search(index - pat-last, index, pat-last, count);
  327.           else
  328.             do-skip(index + skip[as(<fixed-integer>, char)], count);
  329.           end if;
  330.         end if;
  331.           end method,
  332.               method search(index, big-key, pat-key, count)
  333.         case
  334.           pat-key < 0 =>  // End of pattern -- We found one.
  335.             if (count = 1) index
  336.             else do-skip(index + pat-sz, count - 1)
  337.             end if;
  338.           big[big-key] == pattern[pat-key] =>
  339.             // They match -- try one more.
  340.             search(index, big-key - 1, pat-key - 1, count);
  341.           otherwise =>    // Don't match -- try one further along.
  342.             do-skip(index + pat-sz, count);
  343.         end case;
  344.           end method search;
  345.     do-skip(pat-last, count);
  346.       end if;
  347.   end select;
  348. end method subsequence-position;
  349.  
  350. define method replace-elements!(vector :: <vector>,
  351.                 predicate :: <function>,
  352.                 new_value_fn :: <function>,
  353.                 #key count: count) => <vector>;
  354.   for (key from 0 below size(vector),
  355.        until count == 0)
  356.     let this_element = vector[key];
  357.     if (predicate(this_element))
  358.       vector[key] := new_value_fn(this_element);
  359.       if (count) count := count - 1 end if;
  360.     end if;
  361.   end for;
  362.   vector;
  363. end method replace-elements!;
  364.  
  365. // No collection alignment done here because it only handles the
  366. // all-vector case.
  367. define method do(proc :: <function>, vector :: <vector>,
  368.          #next next_method,
  369.          #rest more_vectors)
  370.   if (empty?(more_vectors))
  371.     for (key from 0 below size(vector)) proc(vector[key]) end for;
  372.   elseif (every?(rcurry(instance?, <vector>), more_vectors))
  373.     let size = reduce(method (sz, vec) min(sz, size(vec)) end method,
  374.               size(vector), more_vectors);
  375.     for (key from 0 below size)
  376.       apply(proc, vector[key],
  377.         map(rcurry(element, key), more_vectors));
  378.     end for;
  379.   else
  380.     next_method();
  381.   end if;
  382. end method do;
  383.  
  384. define method fill!(vector :: <vector>, value :: <object>,
  385.             #key start: first = 0, end: last)
  386.   let last = if (last) min(last, size(vector)) else size(vector) end if;
  387.   for (i from first below last)
  388.     vector[i] := value;
  389.   end for;
  390. end method fill!;
  391.  
  392. define method copy-sequence(vector :: <vector>, #key start = 0, end: last)
  393.   let src-sz = size(vector);
  394.   let last = if (last & last < src-sz) last else src-sz end if;
  395.   let sz = if (start <= last) 
  396.          last - start;
  397.        else
  398.          error("End: (%=) is smaller than start: (%=)", last, start);
  399.        end if;
  400.   let result = make(class-for-copy(vector), size: sz);
  401.   for (src-index from start, index from 0 below sz)
  402.     result[index] := vector[src-index];
  403.   end for;
  404.   result;
  405. end method copy-sequence;
  406.  
  407.  
  408. //// Array methods.
  409.  
  410. define method aref (vector :: <vector>, #rest indices)
  411.   if (indices.size == 1)
  412.     vector[indices[0]];
  413.   else
  414.     error("Invalid number of indices for %=.  Expected 1, got %d",
  415.       vector, indices.size);
  416.   end;
  417. end;
  418.  
  419. define method aref-setter (new, vector :: <vector>, #rest indices)
  420.   if (indices.size == 1)
  421.     vector[indices[0]] := new;
  422.   else
  423.     error("Invalid number of indices for %=.  Expected 1, got %d",
  424.       vector, indices.size);
  425.   end;
  426. end;
  427.  
  428. define method size (v :: <vector>) => size :: <fixed-integer>;
  429.   error("The array method for size must be overridden by vectors.");
  430. end;
  431.  
  432. define method dimensions (v :: <vector>) => dimensions :: <sequence>;
  433.   vector (size (v));
  434. end method dimensions;
  435.  
  436.  
  437. //// Special purpose element setter methods.
  438.  
  439. define method element-setter (value, v :: <byte-vector>, index :: <fixed-integer>)
  440.   error("%= is not an integer between 0 and 255.", value);
  441. end;
  442.  
  443. define method element-setter (value, v :: <buffer>, index :: <fixed-integer>)
  444.   error("%= is not an integer between 0 and 255.", value);
  445. end;
  446.  
  447.